﻿#region License
/* ---------------------------------------------------------------- *
 *
 * This file is part of the Xcoordination Application Space
 * ("XcoAppSpace") http://www.xcoordination.com
 *
 * Copyright (C) 2009 Xcoordination http://www.xcoordination.com
 *
 * XcoAppSpace is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General
 * Public License as published by the Free Software Foundation.
 *
 * XcoAppSpace is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/
 * or write to the Free Software Foundation, Inc., 51 Franklin
 * Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * ---------------------------------------------------------------- */
#endregion

using Microsoft.Ccr.Core;
using XcoAppSpaces.Contracts.Service;
using XcoAppSpaces.Core.Configuration;

namespace XcoAppSpaces.Core
{
	/// <summary>
	/// Fluent interface for creating an XcoAppSpace.
	/// </summary>
	public class XcoFluentAppSpaceConfig : IXcoFluentConfiguration, IXcoConfiguration
	{
		private readonly XcoAppSpaceConfig config;

		/// <summary>
		/// Creates a new XcoAppSpaceConfig using a given config string.
		/// </summary>
		/// <param name="configString">The config string that should be used.</param>
		public XcoFluentAppSpaceConfig(string configString)
		{
			config = SpaceStringConfigurator.CreateConfig(configString);
		}
		
		/// <summary>
		/// Creates a new XcoAppSpaceConfig.
		/// </summary>
		public XcoFluentAppSpaceConfig()
		{
			config = new XcoAppSpaceConfig();
		}

		/// <summary>
		/// Creates an XcoAppSpace with the given configuration.
		/// </summary>
		/// <returns>A new XcoAppSpace instance.</returns>
		public XcoAppSpace Create()
		{
			return new XcoAppSpace(this.config);
		}

		/// <summary>
		/// Defines the CCR dispatcher that the XcoAppSpace should use (if not defined, the XcoAppSpace uses its own CCR dispatcher).
		/// </summary>
		/// <param name="ccrDispatcher">The CCR Dispatcher that the XcoAppSpace should use.</param>
		/// <returns>The given XcoAppSpaceConfiguration instance.</returns>
		public XcoFluentAppSpaceConfig UsingCcrDispatcher(Dispatcher ccrDispatcher)
		{
			config.CcrDispatcher = ccrDispatcher;
			return this;
		}

		/// <summary>
		/// Defines a service that the XcoAppSpace should use (if not defined, the default for this type of service is used). An
		/// exception is thrown if the type of service is unknown.
		/// </summary>
		/// <param name="service">The service that the XcoAppSpace should use.</param>
		/// <returns>An XcoFluentServiceConfiguration instance to configure the service.</returns>
		public XcoFluentServiceConfig<T> UsingService<T>(T service)
			where T : IXcoService
		{
			return new XcoFluentServiceConfig<T>(this, config.AddService(service));
		}

		/// <summary>
		/// Defines a certain service instance that should be used by the space. A new service of the given 
		/// type is instantiated. The given type must have a parameterless constructor.
		/// </summary>
		/// <typeparam name="TS">The type of the service.</typeparam>
		/// <returns>A configuration object that can be used to configure this service instance.</returns>
		public XcoFluentServiceConfig<TS> UsingService<TS>() where TS : IXcoService, new()
		{
			return this.UsingService<TS>(new TS());
		}

		/// <summary>
		/// Creates an XcoAppSpace instance from the given configuration object.
		/// </summary>
		/// <param name="config">The configuration object.</param>
		/// <returns>The created XcoAppSpace instance.</returns>
		public static implicit operator XcoAppSpace(XcoFluentAppSpaceConfig config)
		{
			return config.Create();
		}

		#region IXcoConfiguration Members

		/// <summary>
		/// Initializes a service registry instance by adding all services that are configured in 
		/// this XcoAppSpaceConfig instance.
		/// </summary>
		/// <param name="reg">The service registry that should be initialized.</param>
		public void InitServiceRegistry(IXcoServiceRegistry reg)
		{
			config.InitServiceRegistry(reg);
		}

		#endregion
	}
}
